From: Jan Beulich Date: Thu, 18 Aug 2022 07:28:38 +0000 (+0200) Subject: x86/shadow: slightly consolidate sh_unshadow_for_p2m_change() (part II) X-Git-Tag: archive/raspbian/4.17.0-1+rpi1^2~33^2~288 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=241702e064604dbb3e0d9b731aa8f45be448243b;p=xen.git x86/shadow: slightly consolidate sh_unshadow_for_p2m_change() (part II) Pull common checks out of the switch(). This includes extending a _PAGE_PRESENT check to L1 as well, which presumably was deemed redundant with p2m_is_valid() || p2m_is_grant(), but I think we are better off being explicit in all cases. Note that for L2 (or higher) the grant check isn't strictly necessary, as grants are only ever single pages. Leave a respective assertion. With _PAGE_PRESENT checked uniformly, the suspicious mfn_valid(omfn) checks can be dropped rather than moved/folded - if anything we'd need to compare against INVALID_MFN, but that won't come out of l1e_get_mfn(). For L1 replace the moved out condition with a PTE comparison: There's no need for any update or flushing when the two match. Signed-off-by: Jan Beulich Acked-by: Tim Deegan --- diff --git a/xen/arch/x86/mm/shadow/hvm.c b/xen/arch/x86/mm/shadow/hvm.c index fbfae450a0..0c670551f7 100644 --- a/xen/arch/x86/mm/shadow/hvm.c +++ b/xen/arch/x86/mm/shadow/hvm.c @@ -810,19 +810,27 @@ static void cf_check sh_unshadow_for_p2m_change( if ( unlikely(!d->arch.paging.shadow.total_pages) ) return; + /* Only previously present / valid entries need processing. */ + if ( !(oflags & _PAGE_PRESENT) || + (!p2m_is_valid(p2mt) && !p2m_is_grant(p2mt)) ) + return; + switch ( level ) { default: /* * The following assertion is to make sure we don't step on 1GB host - * page support of HVM guest. + * page support of HVM guest. Plus we rely on ->set_entry() to never + * be called with orders above PAGE_ORDER_2M, not even to install + * non-present entries (which in principle ought to be fine even + * without respective large page support). */ - ASSERT(!((oflags & _PAGE_PRESENT) && (oflags & _PAGE_PSE))); + ASSERT(!(oflags & _PAGE_PSE)); break; /* If we're removing an MFN from the p2m, remove it from the shadows too */ case 1: - if ( (p2m_is_valid(p2mt) || p2m_is_grant(p2mt)) && mfn_valid(omfn) ) + if ( l1e_get_intpte(old) != l1e_get_intpte(new) ) { sh_remove_all_shadows_and_parents(d, omfn); if ( sh_remove_all_mappings(d, omfn, _gfn(gfn)) ) @@ -836,10 +844,11 @@ static void cf_check sh_unshadow_for_p2m_change( * scheme, that's OK, but otherwise they must be unshadowed. */ case 2: - if ( !(oflags & _PAGE_PRESENT) || !(oflags & _PAGE_PSE) ) + if ( !(oflags & _PAGE_PSE) ) break; - if ( p2m_is_valid(p2mt) && mfn_valid(omfn) ) + ASSERT(!p2m_is_grant(p2mt)); + { unsigned int i; mfn_t nmfn = l1e_get_mfn(new);